<template>
  <div class="publish-container">
    <!-- 文件选择输入 -->
    <input type="file" ref="fileInput" @change="handleFileSelect" accept="image/*,video/*" style="display: none" multiple>

    <!-- 顶部导航栏 -->
    <div class="header">
      <button @click="goBack" class="back-btn" style = "font-size: 50px;">×</button>
      <h2>{{ currentStep === 'edit' ? '编辑内容' : '发布笔记' }}</h2>
      <button v-if="currentStep === 'edit'" @click="currentStep = 'setup'" class="next-btn">下一步</button>
      <button v-else @click="handlePublish" class="publish-btn" :disabled="isLoading">
        发布
      </button>
    </div>

    <!-- 编辑步骤 -->
    <div v-if="currentStep === 'edit'" class="edit-step">
      <!-- 媒体导航 -->
      <div v-if="publishData.mediaList.length > 1" class="media-nav">
        <button @click="prevMedia" :disabled="publishData.currentMediaIndex === 0" class="nav-btn">&lt;</button>
        <span class="media-counter">
          {{ publishData.currentMediaIndex + 1 }}/{{ publishData.mediaList.length }}
        </span>
        <button @click="nextMedia" :disabled="publishData.currentMediaIndex === publishData.mediaList.length - 1"
          class="nav-btn">&gt;</button>
      </div>

      <!-- 媒体预览区 -->
      <div class="media-preview" style="height: 88vh">
        <div v-if="currentMedia?.type === 'image'" class="media-container">
          <img :src="currentMedia?.original"
            :style="{ filter: publishData.filter !== '原图' ? filterStyles[publishData.filter] : '' }" alt="预览图片"
            ref="mediaElement" @load="setupCanvas" style="display: none">
          <canvas ref="canvas" class="media-canvas"></canvas>
        </div>
        <video v-else-if="currentMedia?.type === 'video'" :src="currentMedia?.original" controls preload="metadata" muted></video>
        <div v-else class="empty-prompt" @click="fileInput?.click()">
          <span class="icon">📷</span>
          <p class="hint-text">点击此处选择图片或视频</p>
          <p class="file-types">支持格式: JPG, PNG, MP4</p>
        </div>
      </div>

      <!-- 编辑工具栏 -->
      <div class="edit-tools">
        <button v-for="tool in tools" :key="tool.name" @click="toggleTool(tool.name)" :class="{
          active: activeTool === tool.name,
          'has-selection': (tool.name === 'sticker' && stickerData.activeSticker) ||
            (tool.name === 'text' && activeText)
        }" :disabled="currentMedia?.type === 'video' && ['filter', 'crop'].includes(tool.name)">
          <span class="icon">{{ tool.icon }}</span>
          <span>{{ tool.label }}</span>
          <span v-if="tool.name === 'sticker' && stickerData.activeSticker" class="badge"></span>
          <span v-if="tool.name === 'text' && activeText" class="badge"></span>
        </button>
      </div>

      <!-- 工具面板 -->
      <div class="tool-panel" v-if="activeTool">
        <!-- 滤镜面板 -->
        <div v-if="activeTool === 'filter'" class="filter-panel">
          <div class="panel-header">
            <h3>选择滤镜</h3>
            <button @click="activeTool = null" class="close-btn">×</button>
          </div>
          <div class="filter-options">
            <div v-for="filter in filters" :key="filter" class="filter-option" @click="applyFilter(filter)"
              :class="{ selected: publishData.filter === filter }">
              <div class="filter-preview" :style="{ background: filterColors[filter] }"></div>
              <span>{{ filter }}</span>
            </div>
          </div>
        </div>

        <!-- 贴纸面板 -->
        <div v-if="activeTool === 'sticker'" class="sticker-panel">
          <div class="panel-header">
            <h3>选择贴纸</h3>
            <button @click="activeTool = null" class="close-btn">×</button>
          </div>
          <div class="sticker-grid">
            <div v-for="i in 12" :key="i" class="sticker-item" @click="addSticker(i)">
              <span class="sticker-emoji">{{ ['😀', '😂', '🤣', '😍', '😎', '🤩', '🥳', '😇', '🤗', '🤔', '🙄', '😏'][i -
                1]
              }}</span>
            </div>
          </div>

          <!-- 贴纸控制按钮 -->
          <div v-if="stickerData.activeSticker" class="sticker-controls">
            <button @click="scaleSticker(0.9)" class="control-btn">缩小</button>
            <button @click="scaleSticker(1.1)" class="control-btn">放大</button>
          </div>
        </div>

        <!-- 文字面板 -->
        <div v-if="activeTool === 'text'" class="text-panel">
          <div class="panel-header">
            <h3>添加文字</h3>
            <button @click="activeTool = null" class="close-btn">×</button>
          </div>
          <div class="text-controls">
            <textarea v-model="textData.content" placeholder="输入文字内容"></textarea>
            <div class="text-options">
              <label>
                颜色:
                <input type="color" v-model="textData.color">
              </label>
              <label>
                大小:
                <input type="range" v-model="textData.size" min="30" max="90">
                {{ textData.size }}px
              </label>
            </div>
            <button @click="addText" class="add-text-btn">添加文字</button>
          </div>
        </div>

        <!-- 裁剪面板 -->
        <div v-if="activeTool === 'crop'" class="crop-panel">
          <div class="panel-header">
            <h3>裁剪图片</h3>
            <button @click="cancelCrop" class="close-btn">×</button>
          </div>
          <div class="crop-controls">
            <div class="crop-options">
              <label>
                比例:
                <select v-model="cropAspectRatio" @change="updateCropAspectRatio">
                  <option :value="0">自由</option>
                  <option :value="1">1:1</option>
                  <option :value="4 / 3">4:3</option>
                  <option :value="16 / 9">16:9</option>
                </select>
                <span class="current-ratio">{{ currentRatioName }}</span>
              </label>
            </div>
            <div class="crop-actions">
              <button @click="applyCrop" class="apply-btn">✔ 确认</button>
              <button @click="cancelCrop" class="cancel-btn">✖ 取消</button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 发布设置步骤 -->
    <div v-else class="setup-step">
      <!-- 缩略图导航 -->
      <div v-if="publishData.mediaList.length > 1" class="thumbnail-nav">
        <div v-for="(item, index) in publishData.mediaList" :key="index" class="thumbnail"
          :class="{ active: index === publishData.currentMediaIndex }" @click="switchMedia(index)">
          <img :src="item.preview" alt="缩略图">
        </div>
      </div>

      <!-- 媒体预览 -->
      <div class="setup-preview">
        <div class="preview-media-container">
          <template v-if="currentMedia">
            <img v-if="currentMedia.type === 'image'" :src="currentMedia.original"
              :style="{ filter: publishData.filter !== '原图' ? filterStyles[publishData.filter] : '' }" alt="预览图片"
              class="preview-media" @load="mediaLoaded" @error="mediaError">
            <video v-else-if="currentMedia.type === 'video'" :src="currentMedia?.original" controls preload="metadata" muted></video>
            <div v-if="mediaLoadError" class="error-preview">
              <span class="icon">❌</span>
              <p>媒体加载失败</p>
              <button @click="retryLoadMedia" class="retry-btn">重试</button>
            </div>
          </template>
          
        </div>
      </div>

      <!-- 发布表单 -->
      <div class="publish-form">
        <!-- 标题输入 -->
        <div class="form-section">
          <label class="form-label">标题</label>
          <div class="input-container">
            <input type="text" v-model="publishData.title" placeholder="输入笔记标题" maxlength="30" class="form-input">
          </div>
        </div>

        <!-- 描述输入 -->
        <div class="form-section">
          <label class="form-label">描述</label>
          <div class="textarea-container">
            <textarea v-model="publishData.description" placeholder="输入笔记详细描述..." maxlength="1000"
              class="form-textarea"></textarea>
          </div>
        </div>

        <!-- 位置信息 -->
        <div class="form-section">
          <label class="form-label">位置</label>
          <div class="location-container">
            <div class="form-item">
              <span class="icon">📍</span>
              <input type="text" v-model="publishData.location" placeholder="添加位置" class="form-input"
                @input="updateTimeLocation">
              <button @click="getCurrentLocation" class="location-btn" :disabled="isGettingLocation">
                {{ isGettingLocation ? '获取中...' : '获取当前位置' }}
              </button>
            </div>
          </div>
        </div>

        <!-- 标签选择 -->
        <div class="form-section">
          <label class="form-label">标签</label>
          <div class="tags-container">
            <div class="tags-scroll">
              <div v-for="tag in popularTags" :key="tag" @click="toggleTag(tag)" class="tag-item"
                :class="{ selected: publishData.tags.includes(tag) }">
                #{{ tag }}
              </div>
            </div>
          </div>
        </div>

        <!-- 可见性设置 -->
        <div class="form-section">
          <label class="form-label">可见性</label>
          <div class="visibility-container">
            <div class="form-item">
              <span class="icon">👀</span>
              <select v-model="publishData.visibility" class="form-select">
                <option value="public">公开</option>
                <option value="friends">仅好友可见</option>
                <option value="private">仅自己可见</option>
              </select>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue';
import { useRouter } from 'vue-router';
import Cropper from 'cropperjs';

// 加载高德地图API
const loadAMap = () => {
  // 使用已验证可用的高德地图API Key
  const key = '133558ca86afa10516c46069d3f0173a';
  console.log('正在加载高德地图API，使用Key:', key);

  return new Promise((resolve, reject) => {
    if (window.AMap) {
      console.log('高德地图已加载，使用现有实例');
      resolve(window.AMap);
      return;
    }

    const script = document.createElement('script');
    script.src = `https://webapi.amap.com/maps?v=1.4.15&key=${key}`;

    script.onload = () => {
      if (window.AMap) {
        console.log('高德地图加载成功');
        resolve(window.AMap);
      } else {
        console.error('高德地图加载失败：window.AMap未定义');
        reject(new Error('高德地图加载失败：window.AMap未定义'));
      }
    };

    script.onerror = (error) => {
      console.error('高德地图脚本加载失败:', error);
      reject(new Error(`高德地图脚本加载失败: ${error.message || '未知错误'}`));
    };

    // 添加超时处理
    const timeoutId = setTimeout(() => {
      console.error('高德地图加载超时');
      reject(new Error('高德地图加载超时'));
      document.head.removeChild(script);
    }, 1000); // 10秒超时

    script.onload = script.onerror = () => {
      clearTimeout(timeoutId);
      if (window.AMap) {
        console.log('高德地图加载成功');
        resolve(window.AMap);
      } else {
        console.error('高德地图加载失败');
        reject(new Error('高德地图加载失败'));
      }
    };

    console.log('正在添加高德地图脚本到DOM');
    document.head.appendChild(script);
  });
};
// 使用CDN引入cropper.css
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css';
document.head.appendChild(link);

const router = useRouter();
const fileInput = ref(null);

// 发布流程状态
const currentStep = ref('edit'); // 'edit' 或 'setup'
const activeTool = ref(null);

// 发布数据
const publishData = ref({
  mediaList: [],
  currentMediaIndex: 0,
  filter: '原图',
  title: '',
  description: '',
  location: '',
  time_location: '',
  tags: [],
  visibility: 'public',
  stickers: [],
  texts: []
});

const updateTimeLocation = () => {
  const now = new Date();
  const timeStr = now.toLocaleString();
  publishData.value.time_location = `${timeStr} ${publishData.value.location}`;
};

// 定位相关状态
const isGettingLocation = ref(false);
const locationError = ref('');

// 贴纸数据
const stickerData = ref({
  activeSticker: null,
  position: { x: 0, y: 0 }
});

// 文字数据 - 确保有默认值
const textData = ref({
  content: '',
  color: '#ffffff',
  size: 16
});

// 计算当前显示的媒体
const currentMedia = computed(() => {
  return publishData.value.mediaList[publishData.value.currentMediaIndex];
});

// 滤镜相关
const filters = ref([
  '原图', '清新', '奶油', '森系', '复古',
  '胶片', '黑白', '美食', '夜景', '人像'
]);

const filterColors = ref({
  '原图': 'none',
  '清新': 'linear-gradient(rgba(255,255,255,0.7), rgba(255,255,255,0.7))',
  '奶油': 'linear-gradient(rgba(255,248,225,0.6), rgba(255,248,225,0.6))',
  '森系': 'linear-gradient(rgba(210,230,210,0.6), rgba(210,230,210,0.6))',
  '复古': 'linear-gradient(rgba(200,180,150,0.5), rgba(200,180,150,0.5))',
  '胶片': 'linear-gradient(rgba(150,150,150,0.3), rgba(150,150,150,0.3))',
  '黑白': 'grayscale(100%)',
  '美食': 'saturate(1.5) contrast(1.1)',
  '夜景': 'brightness(0.9) contrast(1.2)',
  '人像': 'blur(0.5px) brightness(1.05)'
});

const filterStyles = ref({
  '原图': 'none',
  '清新': 'filter: brightness(1.1) contrast(0.9)',
  '奶油': 'filter: brightness(1.05) contrast(0.95) saturate(0.9)',
  '森系': 'filter: hue-rotate(-10deg) brightness(1.05)',
  '复古': 'filter: sepia(0.3) contrast(0.95) brightness(0.95)',
  '胶片': 'filter: contrast(1.1) brightness(0.95)',
  '黑白': 'filter: grayscale(100%)',
  '美食': 'filter: saturate(1.5) contrast(1.1)',
  '夜景': 'filter: brightness(0.9) contrast(1.2)',
  '人像': 'filter: blur(0.5px) brightness(1.05)'
});

// 热门标签
const popularTags = ref(['旅行', '美食', '摄影', '穿搭', '美妆', '生活']);

// 工具切换
const toggleTool = (toolName) => {
  // 如果点击的是当前激活的工具，则关闭工具面板
  if (activeTool.value === toolName) {
    activeTool.value = null;
    stickerData.value.activeSticker = null;
    activeText.value = null;
    return;
  }

  // 切换到新工具前清理旧工具的状态
  if (activeTool.value === 'sticker') {
    stickerData.value.activeSticker = null;
  } else if (activeTool.value === 'text') {
    activeText.value = null;
  } else if (activeTool.value === 'crop' && cropper.value) {
    cancelCrop();
  }

  // 检查视频媒体时禁用不支持的工具
  if (currentMedia.value?.type === 'video') {
    if (['filter', 'crop'].includes(toolName)) {
      showToast('该工具不支持视频编辑');
      return;
    }
  }

  // 激活新工具
  activeTool.value = toolName;

  // 特殊工具初始化
  if (toolName === 'crop') {
    cropImage();
  }
};

// 编辑工具
const tools = computed(() => [
  {
    name: 'filter',
    icon: '🌈',
    label: '滤镜',
    disabled: currentMedia.value?.type === 'video'
  },
  {
    name: 'sticker',
    icon: '✨',
    label: '贴纸'
  },
  {
    name: 'text',
    icon: '🖋️',
    label: '文字'
  },
  {
    name: 'crop',
    icon: '✂️',
    label: '裁剪',
    disabled: currentMedia.value?.type === 'video'
  }
]);

let AMapInstance = null;

// 自动触发文件选择并加载高德地图
onMounted(async () => {
  setTimeout(() => {
    fileInput.value?.click();
  }, 100);

  try {
    AMapInstance = await loadAMap();
    // 自动获取位置
    getCurrentLocation();
  } catch (error) {
    console.error('高德地图加载失败:', error);

  }
});

// 通过经纬度获取地址
const getAddressFromCoords = async (lng, lat) => {
  if (!AMapInstance) {
    console.error('高德地图实例未初始化');
    throw new Error('地图服务未就绪');
  }

  try {
    // 动态加载Geocoder插件
    await new Promise((resolve, reject) => {
      AMapInstance.plugin('AMap.Geocoder', () => {
        resolve();
      });
    });

    const geocoder = new AMapInstance.Geocoder({
      radius: 1000, // 搜索半径
      extensions: 'all' // 返回详细信息
    });

    const result = await new Promise((resolve, reject) => {
      geocoder.getAddress([lng, lat], (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          // 检查返回数据是否有效
          if (!result.regeocode) {
            console.error('逆地理编码返回数据不完整:', result);
            reject(new Error('地址数据不完整'));
            return;
          }
          resolve(result);
        } else {
          console.error('逆地理编码失败:', status, result);
          reject(new Error(result?.message || '地址解析失败'));
        }
      });
    });

    const { addressComponent, formattedAddress } = result.regeocode;

    // 尝试获取区/县信息
    let district = addressComponent?.district;
    if (!district) {
      // 尝试从城市或乡镇获取
      district = addressComponent?.township ||
        addressComponent?.city ||
        addressComponent?.province;
    }

    // 检查是否有有效地址
    if (!district && !formattedAddress) {
      throw new Error('无法获取有效地址信息');
    }

    return {
      district,
      fullAddress: formattedAddress
    };
  } catch (error) {
    console.error('逆地理编码错误:', error);
    throw error; // 重新抛出错误让上层处理
  }
};

// 获取当前位置
const getCurrentLocation = async () => {
  isGettingLocation.value = true;
  locationError.value = '正在获取位置...';

  try {
    // 检查高德地图API是否加载
    if (!AMapInstance) {
      locationError.value = '地图服务初始化中，请稍候...';
      AMapInstance = await loadAMap();
    }

    // 1. 先尝试浏览器原生定位
    try {
      const position = await new Promise((resolve, reject) => {
        if (!navigator.geolocation) {
          throw new Error('浏览器不支持定位功能');
        }

        navigator.geolocation.getCurrentPosition(
          resolve,
          reject,
          { enableHighAccuracy: true, timeout: 10000 }
        );
      });

      const { coords } = position;
      locationError.value = '正在解析位置...';

      try {
        // 使用高德地图逆地理编码获取地址
        const addressInfo = await getAddressFromCoords(coords.longitude, coords.latitude);

        // 优先使用区/县信息，其次使用完整地址的第一部分
        publishData.value.location = addressInfo.district ||
          addressInfo.fullAddress?.split(' ')[0] ||
          '当前位置';
        locationError.value = '';
        return;
      } catch (geocodeError) {
        console.error('逆地理编码失败:', geocodeError);
        // 如果逆地理编码失败，尝试使用高德地图定位
        throw new Error('地址解析失败，尝试其他定位方式');
      }
    } catch (browserError) {
      console.log('浏览器定位失败，尝试高德地图定位:', browserError);
    }

    // 2. 尝试高德地图定位
    if (AMapInstance) {
      locationError.value = '正在通过高德地图获取位置...';

      try {
        const geolocation = await new Promise((resolve) => {
          AMapInstance.plugin('AMap.Geolocation', () => {
            resolve(new AMapInstance.Geolocation({
              enableHighAccuracy: true,
              timeout: 10000,
              showButton: false
            }));
          });
        });

        const result = await new Promise((resolve) => {
          geolocation.getCurrentPosition((status, result) => {
            resolve({ status, result });
          });
        });

        if (result.status === 'complete' && result.result) {
          const address = result.result.formattedAddress || result.result.address || '';
          if (address) {
            // 尝试从地址中提取区/县信息
            const districtMatch = address.match(/(.+?(?:市|区|县)).+?(区|县)/);
            publishData.value.location = districtMatch?.[0] ||
              result.result.addressComponent?.district ||
              address.split(' ')[0];
            locationError.value = '';
            return;
          }
        }

        throw new Error(result.result?.message || '高德地图定位失败');
      } catch (amapError) {
        console.error('高德地图定位失败:', amapError);
        throw new Error('高德地图定位失败');
      }
    }

    throw new Error('所有定位方式均失败');
  } catch (error) {
    console.error('定位失败:', error);
    locationError.value = `定位失败: ${error.message || '未知错误'}`;

    // 添加重试按钮
    locationError.value += ' (点击重试)';
  } finally {
    isGettingLocation.value = false;
  }
};

// 在模板中添加点击重试功能
const onLocationErrorClick = () => {
  if (locationError.value.includes('点击重试')) {
    getCurrentLocation();
  }
};

// 处理文件选择
const handleFileSelect = async (event) => {
  const files = event.target.files;
  if (files.length === 0) return;

  publishData.value.mediaList = [];
  let loadedCount = 0;

  // 显示加载中提示
  showToast('正在处理媒体文件...');

  // 检查WebP支持情况
  const isWebPSupported = await checkWebPSupport();
  console.log('浏览器是否支持WebP格式:', isWebPSupported);

  Array.from(files).forEach(async (file) => {
    const reader = new FileReader();

    reader.onload = async (e) => {
      // 判断是否为图片类型
      if (file.type.startsWith('image/')) {
        // 打印原始图片大小
        console.log(`原始图片 [${file.name}] 大小: ${(file.size / 1024).toFixed(2)} KB, 类型: ${file.type}`);
        
        try {
          // 压缩图片并转换为webp (如果浏览器支持)
          const compressedResult = await compressAndConvertToWebp(e.target.result, file.name, isWebPSupported);
          
          // 从Base64数据URL创建Blob对象，便于上传
          const base64Data = compressedResult.dataUrl.split(',')[1];
          const binaryString = atob(base64Data);
          const bytes = new Uint8Array(binaryString.length);
          for (let i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
          }
          
          // 创建Blob和File对象
          const blob = new Blob([bytes], { type: compressedResult.mimeType });
          const compressedFile = new File(
            [blob], 
            file.name.replace(/\.[^/.]+$/, "") + (compressedResult.format === 'webp' ? '.webp' : '.jpg'), 
            { type: compressedResult.mimeType }
          );
          
          console.log(`压缩后图片文件: 大小=${(compressedFile.size / 1024).toFixed(2)}KB, 类型=${compressedFile.type}`);
          
          publishData.value.mediaList.push({
            file: compressedFile, // 使用压缩后的File对象替代原始文件
            originalFile: file,   // 保留原始文件引用
            type: 'image',
            preview: compressedResult.dataUrl,
            original: compressedResult.dataUrl,
            filtered: compressedResult.dataUrl,
            format: compressedResult.format
          });
        } catch (error) {
          console.error('图片处理失败:', error);
          showToast('图片处理失败，将使用原始图片');
          
          publishData.value.mediaList.push({
            file: file,
            type: 'image',
            preview: e.target.result,
            original: e.target.result,
            filtered: e.target.result,
            format: file.type.split('/')[1]
          });
        }
      } else if (file.type.startsWith('video/')) {
        // 打印原始视频大小
        console.log(`原始视频 [${file.name}] 大小: ${(file.size / (1024 * 1024)).toFixed(2)} MB`);
        
        const maxVideoSizeMB = 5;
        
        // 如果视频大于5MB，尝试压缩
        if (file.size > maxVideoSizeMB * 1024 * 1024) {
          try {
            // 压缩视频
            const compressedVideoURL = await compressVideo(e.target.result, file.name, maxVideoSizeMB);
            
            publishData.value.mediaList.push({
              file: file, // 保留原始文件引用
              type: 'video',
              preview: compressedVideoURL,
              original: compressedVideoURL,
              filtered: compressedVideoURL
            });
          } catch (error) {
            console.error('视频压缩失败:', error);
            // 压缩失败时使用原始视频，但提示用户
            showToast('视频压缩失败，将使用原始文件');
            publishData.value.mediaList.push({
              file: file,
              type: 'video',
              preview: e.target.result,
              original: e.target.result,
              filtered: e.target.result
            });
          }
        } else {
          // 视频小于5MB，直接使用
          console.log(`视频 [${file.name}] 小于${maxVideoSizeMB}MB，无需压缩`);
          publishData.value.mediaList.push({
            file: file,
            type: 'video',
            preview: e.target.result,
            original: e.target.result,
            filtered: e.target.result
          });
        }
      } else {
        // 其他类型文件
        publishData.value.mediaList.push({
          file: file,
          type: 'unknown',
          preview: e.target.result,
          original: e.target.result,
          filtered: e.target.result
        });
      }
      
      loadedCount++;
      if (loadedCount === files.length) {
        currentStep.value = 'edit';
        showToast('媒体处理完成');
      }
    };

    reader.readAsDataURL(file);
  });
};

// 检查浏览器是否支持WebP格式
const checkWebPSupport = () => {
  return new Promise(resolve => {
    const webP = new Image();
    webP.onload = function() { resolve(true); };
    webP.onerror = function() { resolve(false); };
    webP.src = '';
  });
};

// 压缩视频
const compressVideo = (videoDataUrl, fileName, maxSizeMB) => {
  return new Promise((resolve, reject) => {
    // 创建隐藏的视频元素
    const video = document.createElement('video');
    video.style.display = 'none';
    video.muted = true;
    video.autoplay = false;
    document.body.appendChild(video);
    
    // 设置视频源
    video.src = videoDataUrl;
    
    video.onloadedmetadata = () => {
      // 创建视频压缩配置
      const targetBitrate = 1000000; // 初始目标比特率 1Mbps
      const originalDuration = video.duration;
      const originalWidth = video.videoWidth;
      const originalHeight = video.videoHeight;
      
      // 根据原视频尺寸计算合适的输出尺寸
      let outputWidth, outputHeight;
      if (originalWidth > originalHeight) {
        outputWidth = Math.min(originalWidth, 1280);
        outputHeight = Math.round((outputWidth / originalWidth) * originalHeight);
      } else {
        outputHeight = Math.min(originalHeight, 1280);
        outputWidth = Math.round((outputHeight / originalHeight) * originalWidth);
      }
      
      // 创建canvas
      const canvas = document.createElement('canvas');
      canvas.width = outputWidth;
      canvas.height = outputHeight;
      const ctx = canvas.getContext('2d');
      
      // 创建MediaRecorder
      const stream = canvas.captureStream();
      let recorder;
      
      try {
        recorder = new MediaRecorder(stream, {
          mimeType: 'video/webm;codecs=vp9', // 使用VP9编码器
          videoBitsPerSecond: targetBitrate
        });
      } catch (e1) {
        try {
          // 尝试备选编解码器
          recorder = new MediaRecorder(stream, {
            mimeType: 'video/webm;codecs=vp8',
            videoBitsPerSecond: targetBitrate
          });
        } catch (e2) {
          try {
            // 最后尝试不指定编解码器
            recorder = new MediaRecorder(stream, {
              mimeType: 'video/webm',
              videoBitsPerSecond: targetBitrate
            });
          } catch (e3) {
            console.error('不支持的视频编码格式:', e3);
            document.body.removeChild(video);
            reject(new Error('浏览器不支持视频压缩'));
            return;
          }
        }
      }
      
      const chunks = [];
      recorder.ondataavailable = (e) => chunks.push(e.data);
      
      recorder.onstop = async () => {
        // 合并所有块
        const blob = new Blob(chunks, { type: 'video/webm' });
        const compressedSize = blob.size / (1024 * 1024);
        
        console.log(`压缩后视频 [${fileName}] 大小: ${compressedSize.toFixed(2)} MB`);
        
        // 创建视频URL
        const url = URL.createObjectURL(blob);
        
        // 清理DOM元素
        document.body.removeChild(video);
        
        resolve(url);
      };
      
      // 开始录制
      recorder.start(100); // 每100ms生成一个数据块
      
      // 播放视频并绘制到canvas
      video.onplay = () => {
        const draw = () => {
          if (video.paused || video.ended) {
            recorder.stop();
            return;
          }
          
          // 绘制当前帧到canvas
          ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
          requestAnimationFrame(draw);
        };
        
        draw();
      };
      
      // 设置超时保护
      const timeoutId = setTimeout(() => {
        if (recorder.state === 'recording') {
          recorder.stop();
        }
        console.warn('视频压缩已超时，可能结果不完整');
      }, (originalDuration * 1000) + 5000); // 视频时长 + 5秒缓冲
      
      // 播放视频
      video.play().catch(err => {
        console.error('视频播放失败:', err);
        clearTimeout(timeoutId);
        document.body.removeChild(video);
        reject(err);
      });
    };
    
    video.onerror = (err) => {
      console.error('视频加载失败:', err);
      document.body.removeChild(video);
      reject(err);
    };
  });
};

// 压缩图片并转换为webp格式
const compressAndConvertToWebp = (dataUrl, fileName, isWebPSupported) => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      // 创建canvas
      const canvas = document.createElement('canvas');
      
      // 初始压缩参数
      const maxSizeKB = 150; // 目标大小150KB
      const initialQuality = 0.75; // 初始压缩质量
      const minQuality = 0.3; // 最低压缩质量
      let quality = initialQuality;
      let maxDimension = 1200; // 初始最大尺寸
      
      // 决定输出格式
      const outputFormat = isWebPSupported ? 'webp' : 'jpeg';
      const mimeType = `image/${outputFormat}`;
      
      console.log(`压缩图片 [${fileName}] 将使用 ${outputFormat.toUpperCase()} 格式`);
      
      // 递归压缩函数，通过调整质量和尺寸直到达到目标大小
      const compressWithQuality = (currentQuality, currentMaxDimension) => {
        // 计算压缩后的尺寸，保持比例
        let width = img.width;
        let height = img.height;
        
        if (width > currentMaxDimension || height > currentMaxDimension) {
          if (width > height) {
            height = Math.round((height * currentMaxDimension) / width);
            width = currentMaxDimension;
          } else {
            width = Math.round((width * currentMaxDimension) / height);
            height = currentMaxDimension;
          }
        }
        
        canvas.width = width;
        canvas.height = height;
        
        // 绘制图片到canvas
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, width, height);
        
        // 转换为所选格式，设置压缩质量
        const resultDataUrl = canvas.toDataURL(mimeType, currentQuality);
        
        // 计算压缩后的大小 (base64字符串长度 * 3/4 是近似文件大小，单位为字节)
        const compressedSize = resultDataUrl.length * 3/4 / 1024;
        
        console.log(`尝试压缩 [${fileName}] - 质量:${currentQuality.toFixed(2)}, 尺寸:${width}x${height}, 大小:${compressedSize.toFixed(2)}KB, 格式:${outputFormat}`);
        
        // 检查是否达到目标大小
        if (compressedSize <= maxSizeKB || currentQuality <= minQuality) {
          // 已达到目标大小或已达到最低质量
          console.log(`最终压缩 [${fileName}] - 从${(img.src.length * 3/4 / 1024).toFixed(2)}KB压缩到${compressedSize.toFixed(2)}KB (${Math.round((compressedSize / (img.src.length * 3/4 / 1024)) * 100)}% 的原始大小), 格式:${outputFormat}`);
          
          resolve({
            dataUrl: resultDataUrl,
            mimeType: mimeType,
            format: outputFormat,
            width: width,
            height: height,
            quality: currentQuality,
            size: compressedSize
          });
        } else {
          // 尝试降低质量
          if (currentQuality > minQuality) {
            // 根据当前大小与目标大小的比例调整质量
            const nextQuality = Math.max(minQuality, currentQuality * (maxSizeKB / compressedSize) * 0.9);
            compressWithQuality(nextQuality, currentMaxDimension);
          } 
          // 如果质量已经很低，但图片仍然过大，则降低分辨率
          else if (currentMaxDimension > 800) {
            compressWithQuality(minQuality, currentMaxDimension * 0.8);
          } else {
            console.log(`无法将图片 [${fileName}] 压缩到${maxSizeKB}KB以内，最终大小: ${compressedSize.toFixed(2)}KB, 格式:${outputFormat}`);
            
            resolve({
              dataUrl: resultDataUrl,
              mimeType: mimeType,
              format: outputFormat,
              width: width,
              height: height,
              quality: currentQuality,
              size: compressedSize
            });
          }
        }
      };
      
      // 开始压缩
      compressWithQuality(quality, maxDimension);
    };
    
    img.onerror = (error) => {
      console.error('图片加载失败:', error);
      reject(error);
    };
    
    img.src = dataUrl;
  });
};

// 应用滤镜
const applyFilter = (filter) => {
  publishData.value.filter = filter;
  activeTool.value = null;

  // 重新渲染图片应用滤镜
  if (currentMedia.value?.type === 'image' && mediaElement.value && canvas.value) {
    const img = mediaElement.value;
    const canvasEl = canvas.value;
    const ctx = canvasEl.getContext('2d');

    if (img.width && img.height) {
      canvasEl.width = img.width;
      canvasEl.height = img.height;

      // 应用滤镜样式
      ctx.filter = filterStyles.value[filter] || 'none';
      ctx.drawImage(img, 0, 0);

      // 保存滤镜后的图片数据
      const filteredData = canvasEl.toDataURL('image/jpeg', 0.9);
      currentMedia.value.original = filteredData;
      currentMedia.value.preview = filteredData;

      // 重置滤镜以便后续操作
      ctx.filter = 'none';

      // 重新渲染canvas
      setupCanvas();
    }
  }
};

// 媒体导航
const prevMedia = () => {
  if (publishData.value.currentMediaIndex > 0) {
    publishData.value.currentMediaIndex--;
  }
};

const nextMedia = () => {
  if (publishData.value.currentMediaIndex < publishData.value.mediaList.length - 1) {
    publishData.value.currentMediaIndex++;
  }
};

const switchMedia = (index) => {
  publishData.value.currentMediaIndex = index;
};

// 步骤导航
const goBack = () => {
  if (currentStep.value === 'setup') {
    currentStep.value = 'edit';
  } else {
    router.go(-1);
  }
};

const goNext = () => {
  currentStep.value = 'setup';
};

// 贴纸操作
const canvas = ref(null);
const mediaElement = ref(null);
const stickersLoaded = ref([]);

const initCanvas = () => {
  if (!canvas.value || !mediaElement.value) return;

  const img = mediaElement.value;
  const canvasWidth = Math.min(img.width, window.innerWidth * 0.9);
  const canvasHeight = Math.min(img.height, window.innerHeight * 0.7);

  canvas.value.width = canvasWidth;
  canvas.value.height = canvasHeight;

  const ctx = canvas.value.getContext('2d');
  ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);

  // 重新渲染所有贴纸
  renderStickers();
};

const addSticker = (stickerId) => {
  if (!currentMedia.value || !canvas.value) return;

  // 定义emoji数组
  const emojis = ['😀', '😂', '🤣', '😍', '😎', '🤩', '🥳', '😇', '🤗', '🤔', '🙄', '😏'];
  
  // 创建贴纸对象
  const sticker = {
    id: Date.now(),
    stickerId,
    emoji: emojis[stickerId - 1], // 使用对应的emoji
    mediaIndex: publishData.value.currentMediaIndex,
    position: {
      x: canvas.value.width / 2 - 50, // 居中
      y: canvas.value.height / 2 - 50
    },
    size: 100, // 默认大小
    rotation: 0 // 旋转角度
  };

  // 添加到贴纸列表
  publishData.value.stickers.push(sticker);
  stickersLoaded.value.push(sticker);
  
  // 设置当前激活的贴纸
  stickerData.value.activeSticker = sticker.id;
  
  // 重新渲染
  renderCanvas();
  showToast('贴纸已添加，可拖动调整位置');
};

const renderStickers = () => {
  if (!canvas.value || !mediaElement.value) return;

  const ctx = canvas.value.getContext('2d');
  const img = mediaElement.value;
  const canvasWidth = canvas.value.width;
  const canvasHeight = canvas.value.height;

  // 清除并重新绘制基础图片
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);

  // 绘制所有贴纸
  stickersLoaded.value.forEach(sticker => {
    if (sticker.mediaIndex === publishData.value.currentMediaIndex) {
      ctx.save();

      // 移动到贴纸中心
      const centerX = sticker.position.x + sticker.size / 2;
      const centerY = sticker.position.y + sticker.size / 2;
      ctx.translate(centerX, centerY);

      // 应用旋转
      ctx.rotate(sticker.rotation * Math.PI / 180);

      // 绘制贴纸（现在坐标原点在贴纸中心）
      ctx.drawImage(
        sticker.img,
        -sticker.size / 2,
        -sticker.size / 2,
        sticker.size,
        sticker.size
      );

      // 绘制选中贴纸的边框和操作点
      if (stickerData.value.activeSticker === sticker.id) {
        ctx.strokeStyle = '#ff2442';
        ctx.lineWidth = 2;
        ctx.strokeRect(
          -sticker.size / 2 - 2,
          -sticker.size / 2 - 2,
          sticker.size + 4,
          sticker.size + 4
        );

        // 绘制旋转控制点
        ctx.fillStyle = '#ff2442';
        ctx.beginPath();
        ctx.arc(0, -sticker.size / 2 - 15, 5, 0, Math.PI * 2);
        ctx.fill();
      }

      ctx.restore();
    }
  });
};

// 处理贴纸选择
const selectSticker = (e) => {
  if (!canvas.value) return;

  const rect = canvas.value.getBoundingClientRect();
  const scaleX = canvas.value.width / rect.width;
  const scaleY = canvas.value.height / rect.height;

  const x = (e.clientX - rect.left) * scaleX;
  const y = (e.clientY - rect.top) * scaleY;

  const ctx = canvas.value.getContext('2d');
  
  // 检查是否点击了贴纸
  for (const sticker of stickersLoaded.value) {
    if (sticker.mediaIndex !== publishData.value.currentMediaIndex) continue;

    // 计算贴纸边界
    const textWidth = ctx.measureText(sticker.emoji).width;
    const textHeight = sticker.size;

    // 检查点击是否在贴纸范围内
    if (
      x >= sticker.position.x - textWidth/2 &&
      x <= sticker.position.x + textWidth/2 &&
      y >= sticker.position.y - textHeight/2 &&
      y <= sticker.position.y + textHeight/2
    ) {
      stickerData.value.activeSticker = sticker.id;
      stickerData.value.isDragging = true;
      stickerData.value.offset = {
        x: x - sticker.position.x,
        y: y - sticker.position.y
      };
      renderCanvas();
      return;
    }
  }

  // 点击空白处取消选择
  stickerData.value.activeSticker = null;
  renderCanvas();
};

// 处理贴纸拖动和旋转
const startDrag = (e) => {
  if (!stickerData.value.activeSticker) return;
  e.preventDefault();
};

const handleDrag = (e) => {
  if (!stickerData.value.activeSticker || !canvas.value) return;

  const rect = canvas.value.getBoundingClientRect();
  const scaleX = canvas.value.width / rect.width;
  const scaleY = canvas.value.height / rect.height;

  const x = (e.clientX - rect.left) * scaleX;
  const y = (e.clientY - rect.top) * scaleY;

  const sticker = stickersLoaded.value.find(
    s => s.id === stickerData.value.activeSticker
  );

  if (!sticker) return;

  if (stickerData.value.isRotating) {
    // 处理旋转
    const centerX = sticker.position.x + sticker.size / 2;
    const centerY = sticker.position.y + sticker.size / 2;
    const angle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;
    sticker.rotation = stickerData.value.startRotation +
      (angle - stickerData.value.startAngle);
    sticker.rotation = (sticker.rotation + 360) % 360; // 规范化角度
  }
  else if (stickerData.value.isDragging) {
    // 处理拖动
    sticker.position = {
      x: Math.max(0, Math.min(x - stickerData.value.offset.x, canvas.value.width - sticker.size)),
      y: Math.max(0, Math.min(y - stickerData.value.offset.y, canvas.value.height - sticker.size))
    };
  }

  renderStickers();
};

const scaleSticker = (scaleFactor) => {
  if (!stickerData.value.activeSticker || !canvas.value) return;

  const sticker = stickersLoaded.value.find(
    s => s.id === stickerData.value.activeSticker
  );

  if (sticker) {
    const newSize = sticker.size * scaleFactor;

    // 限制最小和最大尺寸
    if (newSize > 20 && newSize < Math.min(canvas.value.width, canvas.value.height)) {
      sticker.size = newSize;
      renderStickers();
    }
  }
};

const stopDrag = () => {
  if (stickerData.value.activeSticker) {
    stickerData.value.isDragging = false;
    stickerData.value.isRotating = false;
  }
};

// 初始化事件监听
onMounted(() => {
  if (canvas.value) {
    canvas.value.addEventListener('mousedown', selectSticker);
    canvas.value.addEventListener('mousemove', handleDrag);
    canvas.value.addEventListener('mouseup', stopDrag);
    canvas.value.addEventListener('mouseleave', stopDrag);

    // 支持鼠标滚轮缩放
    canvas.value.addEventListener('wheel', (e) => {
      if (stickerData.value.activeSticker) {
        e.preventDefault();
        const scaleFactor = e.deltaY < 0 ? 1.1 : 0.9;
        scaleSticker(scaleFactor);
      }
    });
  }
});

// 组件卸载时清理
onUnmounted(() => {
  if (canvas.value) {
    canvas.value.removeEventListener('mousedown', selectSticker);
    canvas.value.removeEventListener('mousemove', handleDrag);
    canvas.value.removeEventListener('mouseup', stopDrag);
    canvas.value.removeEventListener('mouseleave', stopDrag);
  }
});

// 文字操作
const addText = () => {
  // 确保 textData.value 和 content 存在
  if (!currentMedia.value || !textData.value?.content?.trim()) {
    showToast('请输入文字内容');
    return;
  }

  const newText = {
    id: Date.now(),
    content: textData.value.content || '',
    color: textData.value.color || '#ffffff',
    size: parseInt(textData.value.size) || 16,
    mediaIndex: publishData.value.currentMediaIndex,
    position: {
      x: canvas.value ? canvas.value.width / 2 - 50 : 20,
      y: canvas.value ? canvas.value.height / 2 - 20 : 20
    },
    isEditing: true
  };

  publishData.value.texts.push(newText);
  renderCanvas();
  showToast('文字已添加，可拖动调整位置');

  // 不清空内容，方便继续添加类似文字
  // textData.value.content = '';
  // activeTool.value = null;
};

const updateText = (textId, updates) => {
  const index = publishData.value.texts.findIndex(t => t.id === textId);
  if (index !== -1) {
    publishData.value.texts[index] = {
      ...publishData.value.texts[index],
      ...updates
    };
    renderCanvas();
  }
};

const removeText = (textId) => {
  publishData.value.texts = publishData.value.texts.filter(t => t.id !== textId);
  renderCanvas();
  showToast('文字已删除');
};

// 文字选择与拖动
const activeText = ref(null);
const isDraggingText = ref(false);
const dragTextOffset = ref({ x: 0, y: 0 });

const selectText = (e) => {
  if (!canvas.value || activeTool.value !== 'text') return;

  const rect = canvas.value.getBoundingClientRect();
  const scaleX = canvas.value.width / rect.width;
  const scaleY = canvas.value.height / rect.height;

  const x = (e.clientX - rect.left) * scaleX;
  const y = (e.clientY - rect.top) * scaleY;

  // 检查是否点击了文字
  for (const text of publishData.value.texts) {
    if (text.mediaIndex !== publishData.value.currentMediaIndex) continue;

    // 简单计算文字边界框
    const textWidth = text.content.length * text.size * 0.6;
    const textHeight = text.size;

    if (
      x >= text.position.x &&
      x <= text.position.x + textWidth &&
      y >= text.position.y - textHeight &&
      y <= text.position.y
    ) {
      activeText.value = text.id;
      isDraggingText.value = true;
      dragTextOffset.value = {
        x: x - text.position.x,
        y: y - text.position.y
      };
      renderCanvas();
      return;
    }
  }

  // 点击空白处取消选择
  if (activeText.value) {
    activeText.value = null;
    renderCanvas();
  }
};

const dragText = (e) => {
  if (!isDraggingText.value || !activeText.value || !canvas.value) return;

  const rect = canvas.value.getBoundingClientRect();
  const scaleX = canvas.value.width / rect.width;
  const scaleY = canvas.value.height / rect.height;

  const x = (e.clientX - rect.left) * scaleX;
  const y = (e.clientY - rect.top) * scaleY;

  const text = publishData.value.texts.find(t => t.id === activeText.value);
  if (text) {
    text.position = {
      x: Math.max(0, Math.min(x - dragTextOffset.value.x, canvas.value.width - 100)),
      y: Math.max(text.size, Math.min(y - dragTextOffset.value.y, canvas.value.height))
    };
    renderCanvas();
  }
};

const stopDragText = () => {
  isDraggingText.value = false;
};

// 合并渲染函数
const renderCanvas = () => {
  if (!canvas.value || !mediaElement.value) return;

  const ctx = canvas.value.getContext('2d');
  const img = mediaElement.value;
  const canvasWidth = canvas.value.width;
  const canvasHeight = canvas.value.height;

  // 清除并重新绘制基础图片
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);

  // 绘制所有贴纸
  stickersLoaded.value.forEach(sticker => {
  if (sticker.mediaIndex === publishData.value.currentMediaIndex) {
    ctx.save();
    
    // 移动到贴纸位置
    ctx.translate(sticker.position.x, sticker.position.y);
    
    // 应用旋转
    ctx.rotate(sticker.rotation * Math.PI / 180);
    
    // 设置字体大小
    ctx.font = `${sticker.size}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 绘制emoji
    ctx.fillText(sticker.emoji, 0, 0);
    
    // 绘制选中状态边框
    if (stickerData.value.activeSticker === sticker.id) {
      const textWidth = ctx.measureText(sticker.emoji).width;
      ctx.strokeStyle = '#ff2442';
      ctx.lineWidth = 2;
      ctx.strokeRect(
        -textWidth/2 - 5,
        -sticker.size/2 - 5,
        textWidth + 10,
        sticker.size + 10
      );
      
      // 绘制旋转控制点
      ctx.fillStyle = '#ff2442';
      ctx.beginPath();
      ctx.arc(0, -sticker.size/2 - 15, 5, 0, Math.PI * 2);
      ctx.fill();
    }
    
    ctx.restore();
  }
});

  // 绘制所有文字
  publishData.value.texts.forEach(text => {
    if (text.mediaIndex === publishData.value.currentMediaIndex) {
      ctx.save();
      ctx.font = `${text.size}px Arial`;
      ctx.fillStyle = text.color;
      ctx.textBaseline = 'bottom';

      // 绘制文字
      ctx.fillText(text.content, text.position.x, text.position.y);

      // 绘制选中状态边框
      if (activeText.value === text.id) {
        const textWidth = ctx.measureText(text.content).width;
        ctx.strokeStyle = '#ff2442';
        ctx.lineWidth = 2;
        ctx.strokeRect(
          text.position.x - 2,
          text.position.y - text.size - 2,
          textWidth + 4,
          text.size + 4
        );

        // 绘制删除按钮
        ctx.fillStyle = '#ff2442';
        ctx.beginPath();
        ctx.arc(
          text.position.x + textWidth + 15,
          text.position.y - text.size / 2,
          10, 0, Math.PI * 2
        );
        ctx.fill();

        ctx.fillStyle = 'white';
        ctx.font = 'bold 12px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(
          '×',
          text.position.x + textWidth + 15,
          text.position.y - text.size / 2
        );
      }
      ctx.restore();
    }
  });
};

// 更新事件监听
onMounted(() => {
  if (canvas.value) {
    canvas.value.addEventListener('mousedown', (e) => {
      if (activeTool.value === 'text') {
        selectText(e);
      } else {
        selectSticker(e);
      }
    });

    canvas.value.addEventListener('mousemove', (e) => {
      if (isDraggingText.value) {
        dragText(e);
      } else if (stickerData.value.isDragging || stickerData.value.isRotating) {
        handleDrag(e);
      }
    });

    canvas.value.addEventListener('mouseup', () => {
      stopDragText();
      stopDrag();
    });

    canvas.value.addEventListener('mouseleave', () => {
      stopDragText();
      stopDrag();
    });

    // 支持鼠标滚轮缩放当前选中的元素
    canvas.value.addEventListener('wheel', (e) => {
      e.preventDefault();
      if (activeText.value) {
        const text = publishData.value.texts.find(t => t.id === activeText.value);
        if (text) {
          const newSize = text.size + (e.deltaY < 0 ? 2 : -2);
          if (newSize >= 12 && newSize <= 72) {
            text.size = newSize;
            renderCanvas();
          }
        }
      } else if (stickerData.value.activeSticker) {
        const scaleFactor = e.deltaY < 0 ? 1.1 : 0.9;
        scaleSticker(scaleFactor);
      }
    });

    // 点击删除按钮
    canvas.value.addEventListener('click', (e) => {
      if (!activeText.value || !canvas.value) return;

      const rect = canvas.value.getBoundingClientRect();
      const scaleX = canvas.value.width / rect.width;
      const scaleY = canvas.value.height / rect.height;

      const x = (e.clientX - rect.left) * scaleX;
      const y = (e.clientY - rect.top) * scaleY;

      const text = publishData.value.texts.find(t => t.id === activeText.value);
      if (text) {
        const textWidth = canvas.value.getContext('2d').measureText(text.content).width;
        const deleteBtnX = text.position.x + textWidth + 15;
        const deleteBtnY = text.position.y - text.size / 2;
        const distance = Math.sqrt(Math.pow(x - deleteBtnX, 2) + Math.pow(y - deleteBtnY, 2));

        if (distance <= 12) {
          removeText(text.id);
        }
      }
    });
  }
});

// 重命名为 setupCanvas 以避免冲突
const setupCanvas = () => {
  if (!canvas.value || !mediaElement.value) return;

  const img = mediaElement.value;

  // 计算保持原始比例的显示尺寸
  const maxWidth = window.innerWidth * 0.9;
  const maxHeight = window.innerHeight * 0.7;

  let canvasWidth = img.width;
  let canvasHeight = img.height;

  // 按比例缩放以适应容器
  if (canvasWidth > maxWidth || canvasHeight > maxHeight) {
    const ratio = Math.min(maxWidth / canvasWidth, maxHeight / canvasHeight);
    canvasWidth = canvasWidth * ratio;
    canvasHeight = canvasHeight * ratio;
  }

  canvas.value.width = canvasWidth;
  canvas.value.height = canvasHeight;

  const ctx = canvas.value.getContext('2d');
  // 居中绘制图片
  ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);

  // 重新渲染所有元素
  renderCanvas();
};

// 裁剪相关
const cropper = ref(null);
const cropAspectRatio = ref(1);

const currentRatioName = computed(() => {
  return getRatioName(cropAspectRatio.value);
});

const updateCropAspectRatio = () => {
  if (cropper.value) {
    try {
      // 自由比例设为NaN
      const ratio = cropAspectRatio.value === 0 ? NaN : cropAspectRatio.value;
      cropper.value.setAspectRatio(ratio);

      // 重置裁剪框位置和大小
      const imgWidth = cropper.value.image.width;
      const imgHeight = cropper.value.image.height;

      if (ratio && !isNaN(ratio)) {
        // 固定比例模式
        if (imgWidth / imgHeight > ratio) {
          cropper.value.cropBoxData.height = imgHeight * 0.8;
          cropper.value.cropBoxData.width = imgHeight * 0.8 * ratio;
        } else {
          cropper.value.cropBoxData.width = imgWidth * 0.8;
          cropper.value.cropBoxData.height = imgWidth * 0.8 / ratio;
        }
      } else {
        // 自由比例模式
        cropper.value.cropBoxData.width = imgWidth * 0.8;
        cropper.value.cropBoxData.height = imgHeight * 0.8;
      }

      // 居中裁剪框
      cropper.value.cropBoxData.left = (imgWidth - cropper.value.cropBoxData.width) / 2;
      cropper.value.cropBoxData.top = (imgHeight - cropper.value.cropBoxData.height) / 2;

      showToast(`已切换为${getRatioName(cropAspectRatio.value)}比例`);
    } catch (error) {
      console.error('更新裁剪比例失败:', error);
    }
  }
};

const getRatioName = (ratio) => {
  switch (ratio) {
    case 0: return '自由';
    case 1: return '1:1';
    case 4 / 3: return '4:3';
    case 16 / 9: return '16:9';
    default: return '自定义';
  }
};

const cropImage = () => {
  if (!currentMedia.value || currentMedia.value.type !== 'image') {
    showToast('只能裁剪图片');
    return;
  }

  // 隐藏canvas显示原始图片
  mediaElement.value.style.display = 'block';
  canvas.value.style.display = 'none';

  // 销毁已有的cropper实例
  if (cropper.value) {
    cropper.value.destroy();
    cropper.value = null;
  }

  // 初始化Cropper
  nextTick(() => {
    if (mediaElement.value.complete) {
      initCropper();
    } else {
      mediaElement.value.onload = initCropper;
    }
  });
};

const initCropper = () => {
  cropper.value = new Cropper(mediaElement.value, {
    aspectRatio: cropAspectRatio.value || NaN, // 自由比例时为NaN
    viewMode: 1,
    autoCropArea: 0.8,
    responsive: true,
    movable: true,
    zoomable: true,
    rotatable: false,
    scalable: false,
    ready() {
      // 设置初始裁剪框大小
      const containerWidth = this.container.clientWidth;
      const containerHeight = this.container.clientHeight;
      
      // 根据当前比例设置裁剪框
      if (cropAspectRatio.value > 0) {
        const ratio = cropAspectRatio.value;
        if (containerWidth / containerHeight > ratio) {
          this.cropBoxData.height = containerHeight * 0.8;
          this.cropBoxData.width = this.cropBoxData.height * ratio;
        } else {
          this.cropBoxData.width = containerWidth * 0.8;
          this.cropBoxData.height = this.cropBoxData.width / ratio;
        }
      } else {
        // 自由比例
        this.cropBoxData.width = containerWidth * 0.8;
        this.cropBoxData.height = containerHeight * 0.8;
      }
      
      // 居中裁剪框
      this.cropBoxData.left = (containerWidth - this.cropBoxData.width) / 2;
      this.cropBoxData.top = (containerHeight - this.cropBoxData.height) / 2;
    }
  });

  // 监听比例变化
  watch(cropAspectRatio, (newVal) => {
    if (cropper.value && typeof cropper.value.setAspectRatio === 'function') {
      try {
        cropper.value.setAspectRatio(newVal);
      } catch (error) {
        console.error('设置裁剪比例失败:', error);
      }
    }
  });
};

// 应用裁剪
const applyCrop = () => {
  if (!cropper.value) {
    showToast('裁剪器未初始化');
    return;
  }

  try {
    // 获取裁剪后的canvas - 保持原始比例和质量
    const croppedCanvas = cropper.value.getCroppedCanvas({
      minWidth: 512,
      minHeight: 512,
      maxWidth: 4096,
      maxHeight: 4096,
      fillColor: '#fff',
      imageSmoothingEnabled: true,
      imageSmoothingQuality: 'high',
      width: cropper.value.getCroppedCanvas().width, // 保持原始宽度
      height: cropper.value.getCroppedCanvas().height // 保持原始高度
    });

    if (!croppedCanvas) {
      showToast('裁剪失败，请重试');
      return;
    }

    // 更新图片和canvas - 使用高质量JPEG
    currentMedia.value.original = croppedCanvas.toDataURL('image/jpeg', 0.95);
    mediaElement.value.src = currentMedia.value.original;

    // 重新初始化canvas
    mediaElement.value.style.display = 'none';
    canvas.value.style.display = 'block';

    // 确保完全清除cropper的DOM元素
    const cropperContainer = document.querySelector('.cropper-container');
    if (cropperContainer) {
      cropperContainer.remove();
    }

    setupCanvas();

    showToast('裁剪已应用');
  } catch (error) {
    console.error('裁剪错误:', error);
    showToast('裁剪失败');
  } finally {
    // 安全销毁cropper实例
    try {
      if (cropper.value && typeof cropper.value.destroy === 'function') {
        cropper.value.destroy();
      }
    } catch (e) {
      console.error('销毁cropper失败:', e);
    } finally {
      cropper.value = null;
      activeTool.value = null;
    }
  }
};

// 取消裁剪
const cancelCrop = () => {
  if (!cropper.value) {
    activeTool.value = null;
    return;
  }

  try {
    // 恢复显示
    mediaElement.value.style.display = 'none';
    canvas.value.style.display = 'block';

    // 确保清除cropper的DOM元素
    const cropperContainer = document.querySelector('.cropper-container');
    if (cropperContainer) {
      cropperContainer.remove();
    }

    showToast('已取消裁剪');
  } finally {
    // 安全销毁cropper实例
    try {
      if (cropper.value && typeof cropper.value.destroy === 'function') {
        cropper.value.destroy();
      }
    } catch (e) {
      console.error('销毁cropper失败:', e);
    } finally {
      cropper.value = null;
      activeTool.value = null;
    }
  }
};

// 标签操作
const toggleTag = (tag) => {
  const index = publishData.value.tags.indexOf(tag);
  if (index === -1) {
    publishData.value.tags.push(tag);
  } else {
    publishData.value.tags.splice(index, 1);
  }
};

// 发布处理
const isLoading = ref(false);

const toastMessage = ref('');
const showToast = (message) => {
  console.log(message);
  toastMessage.value = message;
  setTimeout(() => {
    toastMessage.value = '';
  }, 3000);
};

// API调用状态
const isCreatingNote = ref(false);
const isUploadingMedia = ref(false);
const uploadProgress = ref(0);

// 上传媒体文件
const uploadMedia = async (noteId, media) => {
  console.log('上传媒体文件 - noteId:', noteId, 'media:', media);

  // 根据文件类型确定media_type
  let mediaType = 'image';
  let file = media.file; // 使用媒体对象中存储的处理后的文件
  
  // 检查文件类型
  if (file.type.startsWith('video/')) {
    mediaType = 'video';
  } else if (file.type.startsWith('image/')) {
    mediaType = 'image';
    console.log(`准备上传图片，文件类型: ${file.type}, 大小: ${(file.size / 1024).toFixed(2)}KB, 文件名: ${file.name}`);
  }

  const formData = new FormData();
  formData.append('media_id', uuidv4());
  formData.append('note_id', noteId);
  formData.append('media_type', mediaType);
  formData.append('file', file);

  try {
    const response = await fetch('http://1.14.98.17:8765/api/media', {
      method: 'POST',
      body: formData
    });

    if (!response.ok) {
      let errorDetail = '媒体上传失败';
      try {
        const errorResponse = await response.json();
        errorDetail = errorResponse.message || JSON.stringify(errorResponse);
      } catch (e) {
        console.error('解析错误响应失败:', e);
      }
      throw new Error(`媒体上传失败: ${errorDetail}`);
    }

    const result = await response.json();
    console.log('媒体上传成功:', result);
    return result;
  } catch (error) {
    console.error('媒体上传错误:', error);
    throw error;
  }
};

const mediaLoadError = ref(false);

const mediaLoaded = () => {
  mediaLoadError.value = false;
  console.log('Media loaded successfully');
};

const mediaError = () => {
  mediaLoadError.value = true;
  console.error('Failed to load media');
};

const retryLoadMedia = () => {
  mediaLoadError.value = false;
  // 强制重新加载媒体
  const media = currentMedia.value;
  if (media) {
    publishData.value.mediaList[publishData.value.currentMediaIndex] = {
      ...media,
      original: media.original + (media.original.includes('?') ? '&' : '?') + 't=' + Date.now()
    };
  }
};

const handlePublish = async () => {
  // 表单验证
  if (!publishData.value.title?.trim()) {
    showToast('请填写标题');
    return;
  }

  if (publishData.value.title.length > 30) {
    showToast('标题不能超过30字');
    return;
  }

  if (!publishData.value.description?.trim()) {
    showToast('请填写描述内容');
    return;
  }

  if (publishData.value.description.length > 1000) {
    showToast('描述内容不能超过1000字');
    return;
  }

  if (publishData.value.mediaList.length === 0) {
    showToast('请至少添加一张图片或视频');
    return;
  }

  // 更新time_location
  updateTimeLocation();

  isLoading.value = true;
  isCreatingNote.value = true;

  try {
    // 1. 从本地存储获取user_id
    const userId = localStorage.getItem('user_id') || '1b329b9a-fb63-454d-a2eb-843d482dd781';
    console.log('使用的用户ID:', userId);

    // 2. 创建笔记 - 生成note_id并包含在请求中
    const noteId = uuidv4(); // 使用自定义的uuid生成函数
    const requestBody = {
      note_id: noteId,
      user_id: userId,
      title: publishData.value.title,
      description: publishData.value.description,
      time_location: publishData.value.time_location
    };
    console.log('创建笔记请求体:', JSON.stringify(requestBody));

    const startTime = Date.now();
    const noteResponse = await fetch('http://1.14.98.17:8765/api/notes', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(requestBody),
    });

    if (!noteResponse.ok) {
      let errorDetail = '笔记创建失败';
      try {
        const errorResponse = await noteResponse.json();
        errorDetail = errorResponse.message || JSON.stringify(errorResponse);
      } catch (e) {
        console.error('解析错误响应失败:', e);
      }
      throw new Error(`笔记创建失败: ${errorDetail}`);
    }

    const endTime = Date.now();
    console.log(`API请求耗时: ${endTime - startTime}ms`);
    console.log('响应状态:', noteResponse.status, noteResponse.statusText);
    console.log('响应Headers:', Object.fromEntries(noteResponse.headers.entries()));

    if (!noteResponse.ok) {
      const errorDetail = await noteResponse.text();
      console.error('创建笔记失败:', errorDetail);
      throw new Error(`创建笔记失败: ${errorDetail}`);
    }

    isCreatingNote.value = false;
    isUploadingMedia.value = true;

    // 3. 上传媒体文件 - 使用前端生成的noteId
    const uploadPromises = publishData.value.mediaList.map((media, index) => {
      return uploadMedia(noteId, media).then(res => {
        uploadProgress.value = Math.floor(((index + 1) / publishData.value.mediaList.length) * 100);
        return res;
      });
    });

    await Promise.all(uploadPromises);

    // 4. 显示成功并跳转
    showToast('发布成功');
    setTimeout(() => {
      router.push('/home');
    }, 1500);

  } catch (error) {
    console.error('发布错误:', error);
    showToast('发布失败，请重试');
  } finally {
    isLoading.value = false;
    isCreatingNote.value = false;
    isUploadingMedia.value = false;
    uploadProgress.value = 0;
  }
};

// 兼容所有环境的UUID生成函数
function uuidv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}
</script>

<style scoped>
.publish-container {
  height: 100vh;
  background-color: #f5f5f5;
  color: #ffffff;
}

/* 公共样式 */
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.back-btn,
.next-btn,
.publish-btn {
  background: none;
  border: none;
  font-size: 22px;
  font-weight: 500;
}

.back-btn {
  color: #666;
  font-size: 24px;
}

.next-btn {
  color: #ff2442;
}

.publish-btn {
  color: #ff2442;
  font-weight: bold;
  font-size: 22px;
  min-width: 80px;
  position: relative;
}

.publish-btn:disabled {
  opacity: 0.7;
  background-color: rgba(255, 36, 66, 0.1);
}

.publish-btn:after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  border: 2px solid transparent;
  border-top-color: #ff2442;
  border-radius: 50%;
  animation: button-spinner 0.6s linear infinite;
  opacity: 0;
}

.publish-btn:disabled:after {
  opacity: 1;
}

@keyframes button-spinner {
  from {
    transform: rotate(0turn);
  }

  to {
    transform: rotate(1turn);
  }
}

.header h2 {
  font-size: 28px;
  font-weight: 600;
  color: #333;
}

/* 媒体编辑样式 */
.media-edit {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.media-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
  padding: 15px 0;
  background-color: rgba(0, 0, 0, 0.5);
  position: absolute;
  bottom: 30vh;
  left: 0;
  right: 0;
  z-index: 2;
}

.nav-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: white;
  font-size: 20px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}

.nav-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.3);
  transform: scale(1.1);
}

.nav-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.media-counter {
  font-size: 16px;
  background: rgba(0, 0, 0, 0.7);
  padding: 5px 15px;
  border-radius: 20px;
  font-weight: bold;
}

.loading-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: white;
  font-size: 14px;
  background: rgba(0, 0, 0, 0.7);
  padding: 8px 16px;
  border-radius: 20px;
  z-index: 2;
}

.setup-preview {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 20px 20px 16px;
  background-color: #f8f8f8;
  border-radius: 12px;
  margin: 0 16px;
}

.preview-media-container {
  width: 100%;
  max-width: 100%;
  max-height: 750px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #fff;
  border-radius: 12px;
  padding: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.preview-media {
  max-width: 750px;
  width: 100%;
  max-height: 750px;
  object-fit: contain;
  border-radius: 4px;
  transition: all 0.3s ease;
  animation: fadeIn 0.5s ease forwards;
}

.publish-form {
  margin-top: 0;
  border-radius: 0 0 12px 12px;
}


video.preview-media {
  background-color: #000;
}

video.preview-media::-webkit-media-controls-panel {
  background: rgba(0, 0, 0, 0.7);
  border-radius: 0 0 4px 4px;
}

video.preview-media::-webkit-media-controls-play-button,
video.preview-media::-webkit-media-controls-mute-button {
  background-color: #ff2442;
  border-radius: 50%;
}

.loading-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.loading-preview::after {
  content: "";
  width: 40px;
  height: 40px;
  border: 4px solid rgba(255, 36, 66, 0.2);
  border-top-color: #ff2442;
  border-radius: 50%;
  animation: loading 1s linear infinite;
}

.error-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px;
  color: #ff2442;
  font-size: 14px;
  text-align: center;
  padding: 20px;
}

.error-preview .icon {
  font-size: 40px;
  margin-bottom: 15px;
}

.retry-btn {
  margin-top: 15px;
  padding: 8px 16px;
  background-color: #ff2442;
  color: white;
  border: none;
  border-radius: 20px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
}


.retry-btn:active {
  transform: translateY(0);
}


.media-preview {
  width: 100%;
  height: calc(100vh - 150px);
  /* 减去顶部导航和工具栏高度 */
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background-color: #000;
}

@media (max-width: 768px) {
  .media-preview {
    height: calc(100vh - 200px);
    /* 在小屏幕上留更多空间 */
  }

  .crop-controls {
    padding: 10px;
  }

  .crop-options {
    flex-direction: column;
    align-items: center;
    gap: 10px;
  }

  .crop-actions {
    flex-direction: column;
    gap: 10px;
  }

  .apply-btn,
  .cancel-btn {
    width: 100%;
    padding: 12px;
  }
}

.media-container {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.media-canvas {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

.media-preview img,
.media-preview video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  object-position: center;
  transition: opacity 0.3s ease;
}

.empty-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 16px;
  text-align: center;
  padding: 20px;
  cursor: pointer;
  transition: all 0.2s ease;
  border-radius: 8px;
  width: 100%;
  height: 100%;
}

.empty-prompt:active {
  transform: scale(0.98);
}

.empty-prompt .icon {
  font-size: 64px;
  margin-bottom: 10px;
  color: #ccc;
  transition: all 0.3s ease;
}

.empty-prompt .hint-text {
  font-size: 14px;
  color: #aaa;
  margin-top: 10px;
  animation: pulse 2s infinite;
}

.empty-prompt .file-types {
  font-size: 12px;
  color: #999;
  margin-top: 5px;
}

.empty-prompt:active {
  transform: scale(0.98);
  background-color: rgba(0, 0, 0, 0.1);
}


.empty-prompt:hover .icon {
  transform: scale(1.1);
}

.empty-prompt .icon {
  font-size: 64px;
  margin-bottom: 15px;
  color: #ccc;
}

.empty-prompt .text {
  max-width: 80%;
  line-height: 1.5;
}



.edit-tools {
  background-color: #333;
  display: flex;
  justify-content: space-around;
  padding: 30px 0;
  border-top: 1px solid #333;
  position: relative;
}

.edit-tools button {
  background: none;
  border: none;
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  position: relative;
  transition: all 0.2s ease;
}

.edit-tools button.active {
  opacity: 1;
  color: #ff2442;
}

.edit-tools button.has-selection {
  opacity: 1;
  color: #4CAF50;
}

.edit-tools button:disabled {
  opacity: 0.3;
}

.edit-tools .icon {
  font-size: 24px;
  transition: all 0.2s ease;
}

.edit-tools .badge {
  position: absolute;
  top: -5px;
  right: 15px;
  width: 8px;
  height: 8px;
  background-color: #4CAF50;
  border-radius: 50%;
  border: 2px solid #333;
}

.edit-tools button.active .icon {
  transform: scale(1.2);
}

.edit-tools button.active.has-selection .icon {
  color: #4CAF50;
  animation: pulse 1.5s infinite;
}

.tool-panel {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 30vh;
  background-color: #2a2a2a;
  padding: 15px;
  overflow-y: auto;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.close-btn {
  background: none;
  border: none;
  color: #fff;
  font-size: 50px;
  cursor: pointer;
  padding: 0 10px;
  transition: all 0.2s ease;
}

.filter-options {
  display: flex;
  gap: 15px;
  overflow-x: auto;
  padding: 10px 0;
}

.filter-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 80px;
}

.filter-preview {
  width: 80px;
  height: 80px;
  border-radius: 5px;
  margin-bottom: 5px;
}

.sticker-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-top: 10px;
}

.sticker-item img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 文字面板样式 */
.text-panel {
  padding: 15px;
}

.text-controls {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.text-controls textarea {
  width: 100%;
  min-height: 80px;
  padding: 10px;
  border-radius: 8px;
  border: 1px solid #444;
  background-color: #333;
  color: #ffffff;
}

.text-options {
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
}

.text-options label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
}

.add-text-btn {
  background-color: #ff2442;
  color: white;
  border: none;
  padding: 8px 15px;
  border-radius: 5px;
  cursor: pointer;
}

/* 裁剪面板样式 */
.crop-controls {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.crop-options {
  display: flex;
  gap: 15px;
}

.crop-options label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #eee;
}

.crop-options select {
  padding: 8px 12px;
  border-radius: 6px;
  background-color: #333;
  color: white;
  border: 1px solid #555;
  font-size: 14px;
  transition: all 0.2s ease;
  min-width: 80px;
}

.crop-options select:focus {
  outline: none;
  border-color: #ff2442;
  box-shadow: 0 0 0 2px rgba(255, 36, 66, 0.3);
}

.crop-options select option {
  padding: 8px;
  background-color: #2a2a2a;
}

.current-ratio {
  display: inline-block;
  margin-left: 8px;
  padding: 4px 8px;
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  font-size: 12px;
  color: #ff2442;
}

.crop-btn {
  background-color: #ff2442;
  color: white;
  border: none;
  padding: 8px 15px;
  border-radius: 5px;
  cursor: pointer;
}

/* 发布设置样式 */
.publish-setup {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #f8f8f8;
  color: #333;
}

.location-container .form-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.location-container .icon {
  font-size: 20px;
  color: #ff2442;
  flex-shrink: 0;
}

.location-container .form-input {
  flex: 1;
  margin-right: 8px;
}

.location-btn {
  background: linear-gradient(135deg, #ff2442, #ff5a5f);
  color: white;
  border: none;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  box-shadow: 0 2px 6px rgba(255, 36, 66, 0.2);
  white-space: nowrap;
}

.location-btn:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 2px 4px rgba(255, 36, 66, 0.2);
}

.location-btn:disabled {
  background: #e0e0e0;
  color: #a0a0a0;
  cursor: not-allowed;
  box-shadow: none;
}

.error-message {
  color: #ff2442;
  font-size: 13px;
  margin-top: 8px;
  padding: 8px 12px;
  background: rgba(255, 36, 66, 0.05);
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  transition: all 0.2s ease;
}

.thumbnail-nav {
  display: flex;
  gap: 10px;
  padding: 10px;
  overflow-x: auto;
  background-color: #fff;
}

.thumbnail {
  width: 60px;
  height: 60px;
  border-radius: 5px;
  overflow: hidden;
  border: 2px solid transparent;
}

.thumbnail.active {
  border-color: #ff2442;
}

.thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.publish-form {
  flex: 1;
  padding: 24px;
  background-color: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
  height: auto;
  min-height: 300px;
  margin: 16px;
  border: 1px solid #f0f0f0;
}

.input-container,
.textarea-container,
.location-container,
.tags-container,
.visibility-container {
  margin-bottom: 16px;
  position: relative;
}

.input-container .character-counter,
.textarea-container .character-counter {
  position: absolute;
  right: 12px;
  bottom: 8px;
  font-size: 12px;
  color: #999;
  background: rgba(255, 255, 255, 0.9);
  padding: 2px 6px;
  border-radius: 10px;
}



.form-label {
  display: block;
  font-size: 25px;
  font-weight: 500;
  color: #333;
  margin-bottom: 10px;
}

.form-input {
  color: #000000;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  font-size: 22px;
  background-color: #fafafa;
  transition: all 0.2s ease;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}


.form-input:focus {
  border-color: #ff2442;
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 36, 66, 0.1);
  background-color: #fff;
}

.form-textarea {
  color: #000;
  width: 100%;
  min-height: 120px;
  padding: 16px;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  font-size: 22px;
  line-height: 1.6;
  resize: vertical;
  background-color: #fafafa;
  transition: all 0.2s ease;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.form-textarea:focus {
  border-color: #ff2442;
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 36, 66, 0.1);
  background-color: #fff;
}

.form-section {
  margin-bottom: 0;
  padding: 0;
  background-color: transparent;
}

.form-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
}

.form-item .icon {
  font-size: 20px;
  flex-shrink: 0;
  color: #666;
}

.tags-container {
  margin-top: 8px;
}

.tags-scroll {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 8px;
  scrollbar-width: none;
  /* Firefox */
  -ms-overflow-style: none;
}

.tags-scroll::-webkit-scrollbar {
  display: none;
}

.tag-item {
  display: inline-flex;
  padding: 10px 18px;
  border-radius: 16px;
  font-size: 20px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  background-color: #f8f8f8;
  color: #555;
  border: 1px solid #eee;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.tag-item.selected {
  background: linear-gradient(135deg, #ff2442, #ff5a5f);
  color: white;
  border-color: transparent;
  box-shadow: 0 2px 8px rgba(255, 36, 66, 0.3);
}

.visibility-container .form-item {
  display: flex;
  align-items: center;
  gap: 12px;
}

.visibility-container .icon {
  font-size: 20px;
  color: #666;
}

.visibility-container .form-select {
  flex: 1;
  padding: 12px 16px;
  padding-right: 40px;
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  font-size: 22px;
  background-color: #fafafa;
  transition: all 0.2s ease;
  appearance: none;
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}


.visibility-container .form-select:focus {
  border-color: #ff2442;
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 36, 66, 0.1);
  background-color: #fff;
}

.character-counter {
  text-align: right;
  font-size: 12px;
  color: #999;
  margin-top: 4px;
}

.error-message {
  color: #ff2442;
  font-size: 12px;
  margin-top: 8px;
}

.form-select {
  flex: 1;
  padding: 12px 16px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  font-size: 15px;
  background-color: #fff;
  appearance: none;
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
}

.form-select:focus {
  border-color: #ff2442;
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 36, 66, 0.2);
}


/* 上传进度条样式 */
.upload-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background-color: #f0f0f0;
  z-index: 1000;
}

.progress-bar {
  height: 100%;
  background-color: #ff2442;
  transition: width 0.3s ease;
}

.progress-text {
  position: fixed;
  top: 10px;
  left: 0;
  right: 0;
  text-align: center;
  color: #ff2442;
  font-size: 14px;
  z-index: 1001;
}



.media-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 裁剪面板样式 */
.crop-panel {
  margin-bottom: 150px;
  padding: 15px;
  background-color: #2a2a2a;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.crop-controls {
  display: flex;
  flex-direction: column;
  gap: 15px;
  max-width: 600px;
  margin: 0 auto;
}

.crop-options {
  display: flex;
  justify-content: center;
  gap: 15px;
  flex-wrap: wrap;
}

.crop-actions {
  display: flex;
  justify-content: center;
  gap: 15px;
  padding-top: 10px;
}

.crop-options label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  color: #eee;
}

.crop-options select {
  padding: 8px 12px;
  border-radius: 8px;
  background-color: #333;
  color: white;
  border: 1px solid #555;
  font-size: 15px;
  min-width: 100px;
}

.crop-options select:focus {
  outline: none;
  border-color: #ff2442;
}

.apply-btn,
.cancel-btn {
  padding: 12px 24px;
  border-radius: 8px;
  font-weight: bold;
  font-size: 15px;
  min-width: 100px;
  border: none;
  cursor: pointer;
  transition: all 0.2s ease;
}

.apply-btn {
  background-color: #4CAF50;
  color: white;
}

.cancel-btn {
  background-color: #f44336;
  color: white;
}

.apply-btn:active,
.cancel-btn:active {
  transform: translateY(0);
}
</style>